package com.octopus.optiworks.controller;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Sha256Hash;
import com.octopus.optiworks.model.Employee;
import com.octopus.optiworks.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/user")
public class UserController {

	private UserValidator userValidator = new UserValidator();

	@Autowired
    private UserService userService;

    @RequestMapping("/manage.o")
    @RequiresPermissions("user:manage")
    public void manage(Model model) {
    	Employee user =  this.userService.getCurrentUser();
    	model.addAttribute("currentUser", user);
        model.addAttribute("users", userService.getAllUsers());
    }

    @RequestMapping(value="/edit.o",method= RequestMethod.GET)
    @RequiresPermissions("user:edit")
    public String showEditUserForm(Model model, @RequestParam Long userId, @ModelAttribute Employee user) {
    	Employee cu =  this.userService.getCurrentUser();
    	model.addAttribute("currentUser", cu);
    	model.addAttribute("action", "Edit");
        Employee u = userService.getUser( userId );
        user.setId(userId);
        user.setUsername(u.getUsername());
        user.setEmail(u.getEmail());
        user.setSerial(u.getSerial());
        user.setTel(u.getTel());
        user.setPassword(Sha256Hash.fromHexString(u.getPassword()).toString());
        user.setRolesId(u.getRolesId());
        user.setTestLightCode(u.getTestLightCode());
        model.addAttribute("roles", this.userService.getAllRoles());
        return "user/edit";
    }

    @RequestMapping(value="/edit.o",method= RequestMethod.POST)
    @RequiresPermissions("user:edit")
    public String editUser(Model model, @RequestParam Long userId, @ModelAttribute Employee user, BindingResult errors) {
    	user.setId(userId);
    	userValidator.validate( user, errors );
        if( errors.hasErrors() ) {
        	model.addAttribute("roles", this.userService.getAllRoles());
        	model.addAttribute("action", "Edit");
            return "user/edit";
        }
        
        if( StringUtils.hasText(user.getPassword()) ) {
            user.setPassword( new Sha256Hash(user.getPassword()).toHex());
        }else{
        	user.setPassword(this.userService.getUser(userId).getPassword());
        }
        try{
        	userService.updateUser( user );
        }catch (org.springframework.jdbc.UncategorizedSQLException e){
        	e.printStackTrace();
        	errors.rejectValue( "username", "error.name.exist", "The name has already existed." );
        	model.addAttribute("action", "Edit");
        	model.addAttribute("roles", this.userService.getAllRoles());
            return "user/edit";
        }
        return "redirect:/user/manage.o";
    }
    
    @RequestMapping(value="/create.o",method= RequestMethod.GET)
    public String showCreateUserForm(Model model, @ModelAttribute Employee user) {
    	Employee cu =  this.userService.getCurrentUser();
    	model.addAttribute("currentUser", cu);
    	model.addAttribute("action", "Create");
    	model.addAttribute("roles", this.userService.getAllRoles());
        return "user/edit";
    }
    
    @RequestMapping(value="/create.o",method= RequestMethod.POST)
    public String createUser(Model model, @ModelAttribute Employee user, BindingResult errors) {
    	userValidator.validate(user, errors );
        if( errors.hasErrors() ) {
        	model.addAttribute("action", "Create");
        	model.addAttribute("roles", this.userService.getAllRoles());
            return "user/edit";
        }
        String password = user.getPassword();
        user.setPassword(new Sha256Hash(password).toHex());
        try{
        	userService.createUser(user, false);
        }catch (org.springframework.dao.DataIntegrityViolationException e){
        	e.printStackTrace();
        	errors.rejectValue( "username", "error.name.exist", "The name has already existed." );
        	model.addAttribute("action", "Create");
        	model.addAttribute("roles", this.userService.getAllRoles());
            return "user/edit";
        }
        return "redirect:/user/manage.o";
    }

    @RequestMapping("/delete.o")
    @RequiresPermissions("user:delete")
    public String deleteUser(@RequestParam Long userId) {
        Assert.isTrue( userId != 1, "Cannot delete admin user" );
        userService.deleteUser( userId );
        return "redirect:/user/manage.o";
    }

}
